<?php
class Arm_Navigation_Sql_Pdo_Mysql extends Arm_Db_Sql_Mysql
{
    /**
     * Arm_Translate_Sql_Pdo_Mysql
     * @var Arm_Translate_Sql_Pdo_Mysql
     */
    protected  $_translateSql = null;
     
    /**
     * Таблица содеражащея названи меню в системе.
     * @var string $_admin_navigation_menu
     */
    const ADMIN_MAVIGATION_MENU = 'admin_navigation_menu';
    
    /**
     * Таблица содержащения переводы для меню
     * @var string
     */
    const ADMIN_MAVIGATION_MENU_TRANSLATE = 'admin_navigation_menu_translate';
    
    /**
     * Таблица содержащея структуры всех меню в системе.
     * @var string
     */
    const ADMIN_NAVIGATION = 'admin_navigation';
    
    /**
     * таблица с данными пунктов навигации
     * @var string
     */
    const ADMIN_NAVIGATION_DATA = 'admin_navigation_data';
    
    public function init()
    {
      $this->_translateSql = Arm_Translate::getInstance()->getSql();
    }
    
    /**
     * Получения меню модуля.
     * @param int $idModule
     * @return array
     */
    public function getMenuModule($idModule)
    {
      $select = $this->_getSelect();
      $select->from(self::ADMIN_MAVIGATION_MENU, 'label');
      $select->where('id_module = ?', $idModule);
      return $this->getDb()->fetchCol($select);
    }
    
    /**
     * Вернет системные меню
     * @return array
     */
    public function getMenuSystem()
    {
      $select = $this->_getSelect();
      $select->from(self::ADMIN_MAVIGATION_MENU, 'label');
      $select->where('id_module = ?', 0);
      return $this->getDb()->fetchCol($select);  
    }
    
    /**
     * Получения всех меню в системе
     * 
     * @return Zend_Db_Select
     */
    public function getMenuAllInfo()
    {
        $select = $this->_getSelect();
        $select->from(self::ADMIN_MAVIGATION_MENU);
        $select = $this->_translateSql->getSelectTranslate(self::ADMIN_MAVIGATION_MENU, 'id', $select);
        $select->order('label');
        return $select;
    }
    
    /**
     * Получения системных меню, их названия.
     */
    public function getMenuSystemName()
    {
         $select = $this->_getSelect();
         $select->from(self::ADMIN_MAVIGATION_MENU, 'label');
         $select->where('id_module=?', 0);
         return $select;
    }
    
    /**
     * Вернет информацию меню
     * 
     * @param int $idMenu
     * @return Zend_Db_Select
     */
    public function getMenuInfo($idMenu)
    {
      $select = $this->getMenuAllInfo();
      $select->where(self::ADMIN_MAVIGATION_MENU . '.id=?', $idMenu);
      return $select;
    }

    /**
     * Создания пункта меню
     * @param int $idNode
     * @param int $idModule
     * @param array $data
     */
    public function createNode($idNode, $idModule, $data)
    {
        // вставляем данные
        $dataTable = $this->_getArrayColumTable(self::ADMIN_NAVIGATION_DATA, $data);
        $dataTable['id_module'] = $idModule;
        $dataTable['id_structure'] = $idNode;
        $this->getDb()->insert(self::ADMIN_NAVIGATION_DATA, $dataTable);
        $idData = $this->getDb()->lastInsertId(self::ADMIN_NAVIGATION_DATA, 'id_data');
        // всталяем данные в таблицу трансляции
        $this->_translateSql->insertTranslate(self::ADMIN_NAVIGATION_DATA, $idData, $data);
        return $idNode;
    }
    
    /**
     * Удаляем элемент(ы) меню
     * @param int|array $idDel
     */
    public function deleteNode($idDel)
    {
      $idDel = (array) $idDel;
      // удаляем данные с таблицы данных, плюс получаем их id
      $select = $this->_getSelect();
      $select->from(self::ADMIN_NAVIGATION_DATA, 'id_data');
      $select->where('id_structure in(?)', $idDel);
      $idDataDel = $this->getDb()->fetchCol($select);
      if($idDataDel === array()) {
          return;
      }
      $this->getDb()->delete(self::ADMIN_NAVIGATION_DATA, $this->getDb()->quoteInto('id_data in(?)', $idDataDel));
      // удалим с таблицы трансляции
      $this->_translateSql->deleteTranslate(self::ADMIN_NAVIGATION_DATA, $idDataDel);
      return;
    }

    /**
     * Создаем меню
     * @param string $name
     * @param string $title
     * @param int $idModule 
     * @return int
     */
    public function createMenu($name, $title, $idModule)
    {
        $this->_db->insert(self::ADMIN_MAVIGATION_MENU, array('label'=>$name, 'id_module'=>$idModule));
        $idMenu = $this->_db->lastInsertId(self::ADMIN_MAVIGATION_MENU);
        //вставка в трасляторскую таблицу
        $this->_translateSql->insertTranslate(self::ADMIN_MAVIGATION_MENU, $idMenu, array('title'=>$title));
        return $idMenu;
    }
    

    /**
     * Получения id узла по url и по id Меню
     * @param unknown_type $url
     * @param unknown_type $idMenu
     */
    public function getIdNodeUrl($url, $idMenu)
    {
     $select = $this->_getSelect();
     $select->from(self::ADMIN_NAVIGATION, 'id');
     $select->join(self::ADMIN_NAVIGATION_DATA, self::ADMIN_NAVIGATION_DATA . '.id_structure=' . self::ADMIN_NAVIGATION . '.id', array());
     $select->where(self::ADMIN_NAVIGATION . '.id_menu=?', $idMenu);
     $select->where(self::ADMIN_NAVIGATION_DATA . '.uri=?', $url);
     return $this->getDb()->fetchOne($select);
    }
    
    /**
     * Вернет id меню по его названию.
     * 
     * @param string $name названия меню.
     * @return int|false
     */
    public function getIdMenu($name)
    {
        $select = $this->_db->select();
        $select->from(self::ADMIN_MAVIGATION_MENU, 'id');
        $select->where('label=?', $name);
        return $this->getDb()->fetchOne($select);
    }
    
    /**
     * Обновления меню. Структрной и таблици с переводами.
     * 
     * @param int $idMenu
     * @param array $data
     * @return void
     */
    public function updateMenu($idMenu, $data)
    {
        // обновим данные в таблице меню
        $dataUpdate = $this->_getArrayColumTable(self::ADMIN_MAVIGATION_MENU, $data);
        if($dataUpdate !== array()) {
            $this->getDb()->update(self::ADMIN_MAVIGATION_MENU, $dataUpdate, $this->getDb()->quoteInto('id=?', $idMenu));
        }
        $this->_translateSql->updateTranslate(self::ADMIN_MAVIGATION_MENU, $idMenu, $data);
        return;
    }
    
    /**
     * Удаления меню с системы
     * @param int $delId id всех пунктов меню
     * @param int $idMEnu id меню
     */
    public function delMenu($idMenu, Arm_Db_Tree_Nested $tree)
    {
        // удаляем все пункты принадлежащие меню
        // сначло получаем все id
        $select = $this->_getSelect();
        $select->from(self::ADMIN_NAVIGATION, 'id');
        $select->where('id_menu = ?', $idMenu);
        $idDelNav = $this->getDb()->fetchCol($select);
        // получаем все ключи с таблицы data
       $select->reset();
       $select->from(self::ADMIN_NAVIGATION_DATA, 'id_data');
       $select->where('id_structure in(?)', $idDelNav);
       $idDelData = $this->getDb()->fetchCol($select);
       // удалям структурные данные
       $tree->deleteTree();
       // удалим с таблицы данных.
       if($idDelData !== array()) {
       $this->getDb()->delete(self::ADMIN_NAVIGATION_DATA, $this->getDb()->quoteInto('id_data in(?)', $idDelData)); 
       // удалим переводы
       $this->_translateSql->deleteTranslate(self::ADMIN_NAVIGATION_DATA, $idDelData);
       }
       // удалим само меню и его данные с таблици переводов.
        $this->getDb()->delete(self::ADMIN_MAVIGATION_MENU, 'id=' . $idMenu);
        // Удалим переводы его описания.
        $this->_translateSql->deleteTranslate(self::ADMIN_MAVIGATION_MENU, $idMenu);
        return;
    }
    
    /**
     * Удаления меню, определеного модуля.
     * @param int $idModule
     * @param Arm_Navigation $navigation
     */
    public function delMenuModule($idModule, Arm_Navigation $navigation)
    {
      $select = $this->_getSelect();
      $select->from(self::ADMIN_MAVIGATION_MENU, 'id');
      $select->where('id_module = ?', $idModule);
      $idMenuArray = $this->getDb()->fetchCol($select);
      foreach ($idMenuArray as $k=>$v) {
        $this->delMenu($v, $navigation->_getTree($v));    
      }
      return;
    }
    
    /**
     * Удаления пунктов меню, на основе idMenu и $idModule
     * @param int $idMenu
     * @param int $idModule
     */
    public function deleteNodesModule($idMenu, $idModule, Arm_Db_Tree_Nested $tree)
    {
       //Arm_Log::system('idMenu ' . $idMenu . ' idModule ' . $idModule);
       $select = $this->_getSelect();
       $select->from(self::ADMIN_NAVIGATION, 'id');
       $select->join(self::ADMIN_NAVIGATION_DATA, self::ADMIN_NAVIGATION . '.id=' . self::ADMIN_NAVIGATION_DATA . '.id_structure', array());   
       $select->where(self::ADMIN_NAVIGATION . '.id_menu=?', $idMenu);
       $select->where(self::ADMIN_NAVIGATION_DATA . '.id_module=?', $idModule);
       //Arm_Log::system((string)$select);
       $idStructure = $this->getDb()->fetchAll($select);
       //Arm_Log::system(print_r($idStructure, true));
       if($idStructure === array()) {
           return;
       }
       
       foreach ($idStructure as $node) {
           $tree->delete($node);
       }
       
       // получим id с таблици данных
       $select->reset();
       $select->from(self::ADMIN_NAVIGATION_DATA, 'id_data');
       $select->where('id_structure in(?)', $idStructure);
       $idData = $this->getDb()->fetchCol($select);
       if($idData === array()) {
           return;
       }
       $this->getDb()->delete(self::ADMIN_NAVIGATION_DATA, $this->getDb()->quoteInto('id_data in(?)', $idData));
       $this->getDb()->delete($this->_translateSql->getNameTableTranslate(self::ADMIN_NAVIGATION_DATA), $this->getDb()->quoteInto('id_node_translate in(?)', $idData));
       return;
    }
    
    /**
     * Вернет id меню для элемента навигации.
     */
    public function getIdMenuNode($idNode)
    {
         $select = $this->getDb()->select();
         $select->from(self::ADMIN_NAVIGATION, 'id_menu');
         $select->where('id=?', $idNode);
         return $this->getDb()->fetchOne($select);
    }
    
    /**
     * Получения данных для одного элемента меню.
     * 
     * @return Zend_Db_Select
     */
    public function getNodeData($idNode)
    {
      $select = $this->getDb()->select();
      $select->from(self::ADMIN_NAVIGATION);
      $select->where(self::ADMIN_NAVIGATION . '.id = ?', $idNode);
      $select->join(self::ADMIN_NAVIGATION_DATA, self::ADMIN_NAVIGATION . '.id=' . self::ADMIN_NAVIGATION_DATA . '.id_structure');   
      $select = $this->_translateSql->getSelectTranslate(self::ADMIN_NAVIGATION_DATA, 'id_data', $select);
      return $select;
    }
    
    /**
     * Присоединит к обьекту select таблицу с данными, переводами.
     * @param Zend_Db_Select $select
     * @return Zend_Db_Select
     */
    public function addTableDataTranslate(Zend_Db_Select $select)
    {
      $select->join(self::ADMIN_NAVIGATION_DATA, self::ADMIN_NAVIGATION_DATA . '.id_structure=' . self::ADMIN_NAVIGATION . '.id');
      $select = $this->_translateSql->getSelectTranslate(self::ADMIN_NAVIGATION_DATA, 'id_data', $select);
      return $select;  
    }
    
    /**
     * Обновления данных, 
     */
    public function updateNode($idNode, $data)
    {
        $array = $this->_getArrayColumTable(self::ADMIN_NAVIGATION_DATA, $data);
        $this->getDb()->update(self::ADMIN_NAVIGATION_DATA, $array, 'id_structure=' . $idNode);
        // получаем id в таблице data
        $select = $this->_getSelect();
        $select->from(self::ADMIN_NAVIGATION_DATA, 'id_data');
        $select->where('id_structure=?', $idNode);
        $idData = $this->getDb()->fetchOne($select);
        $this->_translateSql->updateTranslate(self::ADMIN_NAVIGATION_DATA, $idData, $data);
        return;
    }
    
    /**
     * Запись данных меню в таблицу данных, и таблицу переводов
     * @param $arrayNode
     */
    public function writeMenu($arrayNode)
    {
        // Вставляем в таблицу данных
        $columnsData = $this->_getColumnTable(self::ADMIN_NAVIGATION_DATA);
        $this->_insertMulti(self::ADMIN_NAVIGATION_DATA, $columnsData, $arrayNode, $this->getDb());
        $tt = $this->_translateSql->getNameTableTranslate(self::ADMIN_NAVIGATION_DATA);
        $columnsInsert = $this->_getColumnTable($tt);
        $key = array_search('id_translate', $columnsInsert);
        unset($columnsInsert[$key]);
        $this->_insertMulti($tt, $columnsInsert, $arrayNode, $this->getDb());
        return;
    }
    
    /**
     * Есть ли 
     * @param unknown_type $module
     * @param unknown_type $menu
     * @return bool
     */
    public function isInstallMenuModule($module, $menu)
    {
        $idModule = Arm_Module::getInstance()->getIdModule($module);
        $idMenu   = $this->getIdMenu($menu);
        if($idMenu === false) {
            return false;
        }
        $select   = $this->_getSelect();
        $select->from(self::ADMIN_NAVIGATION_DATA);
        $select->where('id_module=?', $idModule);
        $select->join(self::ADMIN_NAVIGATION, self::ADMIN_NAVIGATION . '.id=' . self::ADMIN_NAVIGATION_DATA . '.id_structure');
        $select->where(self::ADMIN_NAVIGATION . '.id_menu=?', $idMenu);
        $result = $this->getDb()->fetchOne($select);
        if($result === false) {
            return false;
        }
        return true;
    }
    
    /**
     * Вернет максимальный текущий id с таблици данных. 
     */
    public function getLastIdTableData()
    {
     return  $this->_getLastId(self::ADMIN_NAVIGATION_DATA, 'id_data');
    }
    
    /**
     * Вернет данные или обьект Zend_Db_Select для вывода карты сайта
     * @param unknown_type $interface
     * @param unknown_type $select
     */
    public function getMenuDataMapa($interface, $returnSelect=false)
    {
       $select = $this->_getSelect();
       $select->from(self::ADMIN_MAVIGATION_MENU, 'id');
       $select->where('label like ?', $interface . '%');
       $idMenus = $this->_db->fetchCol($select);
       
       $select = $this->_getSelect();
       $select->from(self::ADMIN_NAVIGATION);
       $select->joinLeft(self::ADMIN_NAVIGATION_DATA,  self::ADMIN_NAVIGATION_DATA . '.id_structure=' . self::ADMIN_NAVIGATION . '.id');
       $select = $this->_translateSql->getSelectTranslate(self::ADMIN_NAVIGATION_DATA, 'id_data', $select);
       $select->where(self::ADMIN_NAVIGATION . '.id_menu in(?)', $idMenus);
       
       $select->order(array(self::ADMIN_NAVIGATION . '.id_menu', self::ADMIN_NAVIGATION . '.left_key'));
       $select->group(self::ADMIN_NAVIGATION_DATA . '.uri');

       if($returnSelect === true) {
           return $select;
       }
       return $this->_db->fetchAll($select);
       
    }
}
